[...slug].vue 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <script setup lang="ts">
  2. definePageMeta({
  3. layout: 'docs',
  4. })
  5. const route = useRoute()
  6. const { toc } = useAppConfig()
  7. const { data: page } = await useAsyncData(route.path, () => queryCollection('docs').path(route.path).first())
  8. if (!page.value) {
  9. throw createError({ statusCode: 404, statusMessage: 'Page not found' })
  10. }
  11. const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
  12. return queryCollectionItemSurroundings('docs', route.path, {
  13. fields: ['description'],
  14. })
  15. })
  16. const title = page.value.seo?.title || page.value.title
  17. const description = page.value.seo?.description || page.value.description
  18. useSeoMeta({
  19. title,
  20. ogTitle: title,
  21. description,
  22. ogDescription: description,
  23. twitterTitle: title,
  24. twitterDescription: description,
  25. })
  26. const links = computed(() => {
  27. const links = []
  28. if (toc?.bottom?.edit) {
  29. links.push({
  30. icon: 'i-lucide-external-link',
  31. label: 'Edit this page',
  32. to: `${toc.bottom.edit}/${page?.value?.stem}.${page?.value?.extension}`,
  33. target: '_blank',
  34. })
  35. }
  36. return [...links, ...(toc?.bottom?.links || [])].filter(Boolean)
  37. })
  38. </script>
  39. <template>
  40. <UPage v-if="page">
  41. <UPageHeader
  42. :title="page.title"
  43. :description="page.description"
  44. :links="page.links"
  45. :ui="{
  46. headline: 'uppercase font-mono font-light text-default-500 text-dim',
  47. }"
  48. />
  49. <UPageBody>
  50. <ContentRenderer
  51. v-if="page"
  52. :value="page"
  53. />
  54. <USeparator v-if="surround?.length" />
  55. <UContentSurround :surround="surround" />
  56. </UPageBody>
  57. <template
  58. v-if="page?.body?.toc?.links?.length"
  59. #right
  60. >
  61. <UContentToc
  62. :title="toc?.title"
  63. :links="page.body?.toc?.links"
  64. >
  65. <template
  66. v-if="toc?.bottom"
  67. #bottom
  68. >
  69. <div
  70. class="hidden lg:block space-y-6"
  71. :class="{ '!mt-6': page.body?.toc?.links?.length }"
  72. >
  73. <USeparator
  74. v-if="page.body?.toc?.links?.length"
  75. type="dashed"
  76. />
  77. <UPageLinks
  78. :title="toc.bottom.title"
  79. :links="links"
  80. />
  81. </div>
  82. </template>
  83. </UContentToc>
  84. </template>
  85. </UPage>
  86. </template>